<!-- 
在 Vue 3 中，异步组件是一种按需加载组件的方式，可以有效地减少初始加载时间，提高应用性能。异步组件在被使用时才会被加载，这对于大型应用程序尤为重要。以下是关于 Vue 3 中异步组件的使用说明总结：
  1. 基本用法
  在 Vue 3 中，可以通过  `defineAsyncComponent`  函数来定义异步组件。该函数接受一个工厂函数，该工厂函数返回一个 Promise，Promise 解析为组件定义。
   示例
  import { defineAsyncComponent } from 'vue';

  const AsyncComponent = defineAsyncComponent(() =>
    import('./MyComponent.vue')
  );
  2. 使用异步组件
  定义好异步组件后，可以像普通组件一样在模板中使用它。
   示例
  vue
  <template>
    <div>
      <h1>Welcome to My App</h1>
      <AsyncComponent />
    </div>
  </template>

  <script>
  import { defineAsyncComponent } from 'vue';

  const AsyncComponent = defineAsyncComponent(() =>
    import('./MyComponent.vue')
  );

  export default {
    components: {
      AsyncComponent
    }
  };
  </script>
  3. 加载状态
  在加载异步组件时，可以提供一个加载状态的组件，使用  `defineAsyncComponent`  的第二个参数来指定一个加载组件。
  const AsyncComponent = defineAsyncComponent({
    loader: () => import('./MyComponent.vue'),
    loadingComponent: () => import('./LoadingComponent.vue'),
    delay: 200, // 延迟显示加载组件的时间
    timeout: 3000 // 超时设置
  });
  4. 错误处理
  如果异步组件加载失败，可以提供一个错误组件来处理加载错误。
  const AsyncComponent = defineAsyncComponent({
    loader: () => import('./MyComponent.vue'),
    loadingComponent: () => import('./LoadingComponent.vue'),
    errorComponent: () => import('./ErrorComponent.vue'),
    delay: 200,
    timeout: 3000
  });
  5. 组合 API 和选项 API
  异步组件可以在组合 API 和选项 API 中使用。结合 Vue Router 使用时，异步组件的定义方式是相同的。

   选项 API 示例
  export default {
    components: {
      AsyncComponent: defineAsyncComponent(() => import('./MyComponent.vue'))
    }
  };
  6. 总结
  异步组件在 Vue 3 中提供了一种有效的方式来按需加载组件，减少初始加载时间，提高用户体验。通过使用  `defineAsyncComponent` ，开发者可以轻松地定义异步组件，并处理加载状态和错误情况。理解异步组件的用法，可以帮助开发者优化大型应用的性能。
-->
<template>
  <div class="app">
    <div class="tabs">
      <template v-for="(item, index) in tabs" :key="item">
        <button :class="{ active: currentTab === item }" 
                @click="itemClick(index)">
          {{ Object.keys(item)[0] }}
        </button>
      </template>
    </div>
    <div class="view">
      <!-- is中的组件需要来自两个地方: 1.全局注册的组件 2.局部注册的组件 -->
      <keep-alive include="home,about">
        <component :is="dynamicsCpns"></component>
      </keep-alive>
    </div>
  </div>
</template>

<script setup>
  import { ref, computed, defineAsyncComponent } from "vue";
  import Home from "./views/Home.vue";
  import About from "./views/About.vue";
  // import Category from "./views/Category.vue";
  // const Category = import("./views/Category.vue")
  // 异步组件在打包时会被单独打包成一个文件，在需要的时候才会加载
  const AsyncCategory = defineAsyncComponent(() => import("./views/Category.vue"));

  const tabs = [{"home": Home}, {"about": About}, {"category": AsyncCategory}];
  const currentTab = ref("home");
  const currentIndex = ref(0);

  const itemClick = (index) => {
    currentIndex.value = index;
  };

  const dynamicsCpns = computed(() => {
    return tabs[currentIndex.value][Object.keys(tabs[currentIndex.value])[0]]
  })

</script>

<style lang="scss" scoped>
  .tab-bar {
    display: flex;
    background-color: #f2f2f2;

    .tab-bar-item {
      flex: 1;
      text-align: center;
      line-height: 50px;
    }
  }

</style>